package com.itheim.orderservice.rabbitmq;

import com.rabbitmq.client.*;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class RabbitConsumer {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @RabbitListener(queues = "user_queue_001")
    @RabbitHandler
    public void onMessage(Message build, Channel channel) throws IOException {
        //if (!build.getMessageProperties().getMessageId().isEmpty()){
            //表示是否成功设置了值
            //if (stringRedisTemplate.opsForValue().setIfAbsent(build.getMessageProperties().getMessageId(), "1")) {
                try {
                    System.out.println("已经接收到消息了");
                    //int a = 1 / 0;
                    String messageId = build.getMessageProperties().getMessageId();
                    //todo::Unknown--发送者可以讲msg的管理消息设置id为uuid,此时同样可以达到消息唯一,但并未发现儿二者的区别
                    String correlationId = build.getMessageProperties().getCorrelationId();
                    System.out.println(correlationId);
                    //者两个sout打印的结果都是在发送者设置的,均可以完成消息唯一性的功能
                    System.out.println(messageId);
                    //ack表示手动确认消息。multiple：false只确认该delivery_tag的消息，true确认该delivery_tag的所有消息
                    channel.basicAck(build.getMessageProperties().getDeliveryTag(), false);
                    //rabbitmq是使用二进制来传递消息的,需要指定二进制才能变回原来的类型
                    System.out.println("接收到的消息" + new String(build.getBody(), "UTF-8"));
                } catch (Exception e) {
                    System.out.println("消费失败重试");
                    stringRedisTemplate.delete(build.getMessageProperties().getMessageId());
                    //todo::bug--第三个参数是true的时候会出现一直投递消息的问题，配置不管用。而设置为false的时候表示不重新投递消息
                    channel.basicNack(build.getMessageProperties().getDeliveryTag(), false, true);
                }
            }
            //System.out.println("已经拒绝了消息");
            //设置值失败,意味着消息已经被消费过了,所以此处需要跳出
//            return;
//        }
//        throw new RuntimeException("没有传递消息id,实现消息幂等性");
//    }
}
